﻿using BeerXMLWPF.Models;
using BeerXMLWPF.ViewModels;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace BeerXMLWPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<Information> lstIn;
        private List<string> lstCombobox;
        string filename = "";
        Recipe r;
        public MainWindow()
        {
            InitializeComponent();
            lstIn = new ObservableCollection<Information>();
            r = XMLParser.ParseByXDocument("Cromwell Bitter.xml");
            LoadXML(r);
            lstCombobox = new List<string>();
            lstCombobox.Add("Extract");
            lstCombobox.Add("Partial Mash");
            lstCombobox.Add("All Grain");
            cbType.ItemsSource = lstCombobox;
        }
        private void LoadXML(Recipe r)
        {
            if (r != null)
            {
                txtName.Text = r.Name;
                cbType.SelectedItem = r.Type;
                txtBoilTime.Text = r.Boil_Time;
                txtBrewer.Text = r.Brewer;
                txtDate.Text = r.Date;
                txtBatchSize.Text = r.Batch_Size;
                txtEquipment.Text = r.Equipment.Name;
                txtVersion.Text = r.Version;
                txtTotEfficiency.Text = r.Efficiency;
                txtBoilSize.Text = r.Boil_Size;
                foreach (var hop in r.Hops)
                {
                    lstIn.Add(new Information
                    {
                        Name = hop.Name,
                        Amount = hop.Display_Amount,
                        Type = "Hop"
                    });
                }
                foreach (var fer in r.Fermentables)
                {
                    lstIn.Add(new Information
                    {
                        Name = fer.Name,
                        Amount = fer.Display_Amount,
                        Type = "Fermentable"
                    });
                }
                foreach (var misc in r.Miscs)
                {
                    lstIn.Add(new Information
                    {
                        Name = misc.Name,
                        Amount = misc.Display_Amount,
                        Type = "Misc"
                    });
                }
                foreach (var yeast in r.Yeasts)
                {
                    lstIn.Add(new Information
                    {
                        Name = yeast.Name,
                        Amount = yeast.Display_Amount,
                        Type = "Yeast"
                    });
                }
                foreach (var water in r.Waters)
                {
                    lstIn.Add(new Information
                    {
                        Name = water.Name,
                        Amount = water.Display_Amount,
                        Type = "Water"
                    });
                }
                grdInfo.ItemsSource = lstIn;
            }

        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            lstIn.Clear();
            // Create OpenFileDialog
            OpenFileDialog dlg = new OpenFileDialog();
            // Set filter for file extension and default file extension
            dlg.DefaultExt = ".xml";
            dlg.Filter = "XML documents (.xml)|*.xml";
            // Display OpenFileDialog by calling ShowDialog method
            Nullable<bool> result = dlg.ShowDialog();

            // Get the selected file name and display in a TextBox
            if (result == true)
            {
                // Open document
                Recipe recipe = XMLParser.ParseByXDocument(dlg.FileName);
                LoadXML(recipe);
                filename = dlg.FileName;
                r = recipe;
                btnSave.IsEnabled = true;
            }
        }

        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Information item = (Information)grdInfo.SelectedItem;
                switch (item.Type)
                {
                    case "Hop":
                        Global.hop = findHop(item);
                        var editHop = new EditHop("edit");
                        editHop.Title = "Edit Hop";
                        editHop.Closed += edit_Closed;
                        editHop.Show();
                        break;
                    case "Fermentable":
                        Global.fermentable = findFermentable(item);
                        var editFer = new AddFermentable("edit");
                        editFer.Title = "Edit Fermentable";
                        editFer.Closed += editFer_Closed;
                        editFer.Show();
                        break;
                    case "Misc":
                        Global.misc = findMisc(item);
                        var editMisc = new EditMisc("edit");
                        editMisc.Title = "Edit Misc";
                        editMisc.Closed += editMisc_Closed;
                        editMisc.Show();
                        break;
                    case "Yeast":
                        Global.yeast = findYeast(item);
                        var editYeast = new EditYeast("edit");
                        editYeast.Title = "Edit Yeast";
                        editYeast.Closed += editYeast_Closed;
                        editYeast.Show();
                        break;
                    case "Water":
                        Global.water = findWater(item);
                        var editWater = new EditWater();
                        editWater.Title = "Edit Water";
                        editWater.Closed += editWater_Closed;
                        editWater.Show();
                        break;
                }

                //lstIn.Remove(item);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
                MessageBox.Show("You must select an item in grid");
            }
        }

        void editWater_Closed(object sender, EventArgs e)
        {
            Information item = (Information)grdInfo.SelectedItem;
            item.Name = Global.water.Name;
            item.Amount = Global.water.Display_Amount;
            var water = findWater(item);
            water = Global.water;
            Global.water = null;
            grdInfo.ItemsSource = null;
            grdInfo.ItemsSource = lstIn;
        }

        void editYeast_Closed(object sender, EventArgs e)
        {
            Information item = (Information)grdInfo.SelectedItem;
            item.Name = Global.yeast.Name;
            item.Amount = Global.yeast.Display_Amount;
            var yeast = findYeast(item);
            yeast = Global.yeast;
            Global.yeast = null;
            grdInfo.ItemsSource = null;
            grdInfo.ItemsSource = lstIn;
        }

        void editMisc_Closed(object sender, EventArgs e)
        {
            Information item = (Information)grdInfo.SelectedItem;
            item.Name = Global.misc.Name;
            item.Amount = Global.misc.Display_Amount;
            var fer = findMisc(item);
            fer = Global.misc;
            Global.misc = null;
            grdInfo.ItemsSource = null;
            grdInfo.ItemsSource = lstIn;
        }

        void editFer_Closed(object sender, EventArgs e)
        {
            Information item = (Information)grdInfo.SelectedItem;
            item.Name = Global.fermentable.Name;
            item.Amount = Global.fermentable.Display_Amount;
            var fer = findFermentable(item);
            fer = Global.fermentable;
            Global.fermentable = null;
            grdInfo.ItemsSource = null;
            grdInfo.ItemsSource = lstIn;
        }

        void edit_Closed(object sender, EventArgs e)
        {
            Information item = (Information)grdInfo.SelectedItem;
            item.Name = Global.hop.Name;
            item.Amount = Global.hop.Display_Amount;
            var hop = findHop(item);
            hop = Global.hop;
            Global.hop = null;
            grdInfo.ItemsSource = null;
            grdInfo.ItemsSource = lstIn;
        }
        private Hop findHop(Information item)
        {
            foreach (Hop h in r.Hops)
            {
                if (h.Name == item.Name && h.Display_Amount == item.Amount) return h;
            }
            return null;
        }
        private Fermentable findFermentable(Information item)
        {
            foreach (Fermentable h in r.Fermentables)
            {
                if (h.Name == item.Name && h.Display_Amount == item.Amount) return h;
            }
            return null;
        }
        private Misc findMisc(Information item)
        {
            foreach (Misc h in r.Miscs)
            {
                if (h.Name == item.Name && h.Display_Amount == item.Amount) return h;
            }
            return null;
        }
        private Yeast findYeast(Information item)
        {
            foreach (Yeast h in r.Yeasts)
            {
                if (h.Name == item.Name && h.Display_Amount == item.Amount) return h;
            }
            return null;
        }
        private Water findWater(Information item)
        {
            foreach (Water h in r.Waters)
            {
                if (h.Name == item.Name && h.Display_Amount == item.Amount) return h;
            }
            return null;
        }
        private void btnAddHop_Click(object sender, RoutedEventArgs e)
        {
            var addHop = new EditHop();
            addHop.Title = "Add Hop";
            addHop.Closed += addHop_Closed;
            addHop.Show();
        }

        void addHop_Closed(object sender, EventArgs e)
        {
            if (Global.OK)
            {
                r.Hops.Add(Global.hop);
                lstIn.Add(new Information
                {
                    Name = Global.hop.Name,
                    Type = "Hop",
                    Amount = Global.hop.Display_Amount
                });
                Global.OK = false;
            }
        }

        private void btnAddWater_Click(object sender, RoutedEventArgs e)
        {
            var addWater = new EditWater();
            addWater.Title = "Add Water";
            addWater.Closed += addWater_Closed;
            addWater.Show();
        }

        void addWater_Closed(object sender, EventArgs e)
        {
            if (Global.OK)
            {
                r.Waters.Add(Global.water);
                lstIn.Add(new Information
                {
                    Name = Global.water.Name,
                    Type = "Water",
                    Amount = Global.water.Display_Amount
                });
                Global.OK = false;
            }
        }

        private void btnAddYeast_Click(object sender, RoutedEventArgs e)
        {
            var addYeast = new EditYeast();
            addYeast.Title = "Add Yeast";
            addYeast.Closed += addYeast_Closed;
            addYeast.Show();
        }

        void addYeast_Closed(object sender, EventArgs e)
        {
            if (Global.OK)
            {
                r.Yeasts.Add(Global.yeast);
                lstIn.Add(new Information
                {
                    Name = Global.yeast.Name,
                    Type = "Yeast",
                    Amount = Global.yeast.Display_Amount
                });
                Global.OK = false;
            }
        }

        private void btnAddMisc_Click(object sender, RoutedEventArgs e)
        {
            var addMisc = new EditMisc();
            addMisc.Title = "Add Misc";
            addMisc.Closed += addMisc_Closed;
            addMisc.Show();
        }

        void addMisc_Closed(object sender, EventArgs e)
        {
            if (Global.OK)
            {
                r.Miscs.Add(Global.misc);
                lstIn.Add(new Information
                {
                    Name = Global.misc.Name,
                    Type = "Misc",
                    Amount = Global.misc.Display_Amount
                });
                Global.OK = false;
            }
        }

        private void btnAddFermentable_Click(object sender, RoutedEventArgs e)
        {
            var addFer = new AddFermentable();
            addFer.Title = "Add Fer";
            addFer.Closed += addFer_Closed;
            addFer.Show();
        }

        void addFer_Closed(object sender, EventArgs e)
        {
            if (Global.OK)
            {
                r.Fermentables.Add(Global.fermentable);
                lstIn.Add(new Information
                {
                    Name = Global.fermentable.Name,
                    Type = "Fermentable",
                    Amount = Global.fermentable.Display_Amount
                });
                Global.OK = false;
            }
        }

        private void btnCreateNewRecipe_Click(object sender, RoutedEventArgs e)
        {
            ClearWindows();
            btnSave.IsEnabled = false;
        }

        private void ClearWindows()
        {
            txtBatchSize.Text = "";
            txtBoilSize.Text = "";
            txtBoilTime.Text = "";
            txtBrewer.Text = "";
            txtDate.Text = "";
            txtName.Text = "";
            txtTotEfficiency.Text = "";
            txtVersion.Text = "1";
            cbType.SelectedItem = "All Grain";
            lstIn.Clear();
            grdInfo.ItemsSource = lstIn;
            r.Hops.Clear();
            r.Miscs.Clear();
            r.Fermentables.Clear();
            r.Yeasts.Clear();
            r.Waters.Clear();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (txtName.Text == "")
            {
                MessageBox.Show("You must enter name of recipe");
                return;
            }
            if (txtBrewer.Text == "")
            {
                MessageBox.Show("You must enter name of brewer");
                return;
            }
            try
            {
                string s = txtBoilTime.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0)
                {
                    MessageBox.Show("Boil Time must be a integer and greater than 0");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Boil Time must be a integer and greater than 0");
                return;
            }
            try
            {
                string s = txtBatchSize.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0)
                {
                    MessageBox.Show("Batch Size must be a integer and greater than 0");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Batch Size must be a integer and greater than 0");
                return;
            }
            try
            {
                string s = txtBoilSize.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0)
                {
                    MessageBox.Show("Boil Size must be a integer and greater than 0");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Boil Size must be a integer and greater than 0");
                return;
            }
            try
            {
                string s = txtTotEfficiency.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0 || time > 100)
                {
                    MessageBox.Show("Efficency must be a integer and greater than 0 and less than 100");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Efficency must be a integer and greater than 0 and less than 100");
                return;
            }
            try
            {
                DateTime date = DateTime.Parse(txtDate.Text);
                r.Date = date.ToShortDateString();
            }
            catch
            {
                MessageBox.Show("Date is not correct format");
                return;
            }

            r.Name = txtName.Text;
            r.Brewer = txtBrewer.Text;
            r.Boil_Size = txtBoilSize.Text;
            r.Display_Boil_Size = r.Boil_Size + " l";
            r.Batch_Size = txtBatchSize.Text;
            r.Boil_Time = txtBoilTime.Text;
            r.Date = txtDate.Text;
            r.Efficiency = txtTotEfficiency.Text;
            r.Type = cbType.SelectedItem.ToString();
            XMLParser.WriteXML(r, filename);
            MessageBox.Show("Recipe saved");
        }

        private void btnSaveNewFile_Click(object sender, RoutedEventArgs e)
        {
            if (txtName.Text == "")
            {
                MessageBox.Show("You must enter name of recipe");
                return;
            }
            if (txtBrewer.Text == "")
            {
                MessageBox.Show("You must enter name of brewer");
                return;
            }
            try
            {
                string s = txtBoilTime.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0)
                {
                    MessageBox.Show("Boil Time must be a integer and greater than 0");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Boil Time must be a integer and greater than 0");
                return;
            }
            try
            {
                string s = txtBatchSize.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0)
                {
                    MessageBox.Show("Batch Size must be a integer and greater than 0");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Batch Size must be a integer and greater than 0");
                return;
            }
            try
            {
                string s = txtBoilSize.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0)
                {
                    MessageBox.Show("Boil Size must be a integer and greater than 0");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Boil Size must be a integer and greater than 0");
                return;
            }
            try
            {
                string s = txtTotEfficiency.Text.Trim().Split(' ')[0];
                double time = double.Parse(s);
                if (time <= 0)
                {
                    MessageBox.Show("Efficency must be a integer and greater than 0");
                    return;
                }
            }
            catch
            {
                MessageBox.Show("Efficency must be a integer and greater than 0");
                return;
            }
            r.Name = txtName.Text;
            r.Brewer = txtBrewer.Text;
            r.Boil_Size = txtBoilSize.Text;
            r.Display_Boil_Size = r.Boil_Size + " l";
            r.Batch_Size = txtBatchSize.Text;
            r.Boil_Time = txtBoilTime.Text;
            r.Date = txtDate.Text;
            r.Efficiency = txtTotEfficiency.Text;
            r.Type = cbType.SelectedItem.ToString();
            SaveFileDialog savedlg = new SaveFileDialog();
            savedlg.FileName = "NewXMLDocument"; // Default file name
            savedlg.DefaultExt = ".xml"; // Default file extension
            savedlg.Filter = "XML Documents (.xml)|*.xml"; // Filter files by extension 

            // Show save file dialog box
            Nullable<bool> sresult = savedlg.ShowDialog();

            // Process save file dialog box results 
            if (sresult == true)
            {
                // Save document 
                XMLParser.WriteXML(r, savedlg.FileName);
                filename = savedlg.FileName;
                btnSave.IsEnabled = true;
            }
        }

        private void btnExit_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnRemove_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Information item = (Information)grdInfo.SelectedItem;
                if (MessageBox.Show("Are you sure you want to delete this item?", "Delete Item", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    lstIn.Remove(item);
                    switch (item.Type)
                    {
                        case "Hop":

                            r.Hops.Remove(findHop(item));


                            break;
                        case "Fermentable":
                            r.Fermentables.Remove(findFermentable(item));

                            break;
                        case "Misc":
                            r.Miscs.Remove(findMisc(item));

                            break;
                        case "Yeast":
                            r.Yeasts.Remove(findYeast(item));

                            break;
                        case "Water":
                            r.Waters.Remove(findWater(item));
                            break;
                    }


                }

                //lstIn.Remove(item);
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.ToString());
                MessageBox.Show("You must select an item in grid");
            }
        }
    }
}
